package upload

import (
	"context"
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"github.com/satori/go.uuid"
	"github.com/zeromicro/go-zero/core/logx"
	"group-card/api/internal/svc"
	"group-card/api/internal/types"
	"group-card/common/response"
	"mime/multipart"
	"net/http"
	"path"
)

type UploadsLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
	r      *http.Request
}

func NewUploadsLogic(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request) *UploadsLogic {
	return &UploadsLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
		r:      r,
	}
}

func (l *UploadsLogic) Uploads(req *types.UploadRequest) (resp *types.UploadResponse, err error) {

	files := l.r.MultipartForm.File["multiplefiles"]
	if len(files) == 0 {
		return &types.UploadResponse{Code: response.ErrCode, Message: "请上传文件"}, err
	}

	var paths []string
	for _, file := range files {
		ossPath, err := l.UploadOss(file)
		if err != nil {
			return &types.UploadResponse{Code: response.ErrCode, Message: "上传文件失败"}, err
		}
		paths = append(paths, ossPath)
	}

	return &types.UploadResponse{
		Code:    response.SuccessCode,
		Message: "上传文件成功",
		Data:    paths,
	}, nil
}

// region TODO: 普通上传到oss Author:LiuYanLin Date:2023/03/16 周四 16:43

func (l *UploadsLogic) UploadOss(file *multipart.FileHeader) (ossPath string, err error) {

	// 获取存储空间。
	bucket, err := l.svcCtx.OssClient.Bucket(l.svcCtx.Config.Oss.Bucket)
	if err != nil {
		return
	}

	// 根据配置文件进行指定存储类型
	var storageType oss.Option
	switch l.svcCtx.Config.Oss.StorageClassType {
	case "Standard": // 指定存储类型为标准存储，缺省也为标准存储。
		storageType = oss.ObjectStorageClass(oss.StorageStandard)
	case "IA": // 指定存储类型为很少访问存储
		storageType = oss.ObjectStorageClass(oss.StorageIA)
	case "Archive": // 指定存储类型为归档存储。
		storageType = oss.ObjectStorageClass(oss.StorageArchive)
	case "ColdArchive": // 指定存储类型为归档存储。
		storageType = oss.ObjectStorageClass(oss.StorageColdArchive)
	default:
		storageType = oss.ObjectStorageClass(oss.StorageStandard)
	}

	//获取文件的后缀名
	ext := path.Ext(file.Filename)

	//文件唯一值
	md5 := fmt.Sprintf("%s", uuid.NewV4())

	// 文件对象名
	objectName := l.svcCtx.Config.Oss.Folder + "/" + md5 + ext

	// 文件类型
	objectType := oss.ContentType("upload/" + ext[1:])

	// 指定访问权限为公共读，缺省为继承bucket的权限。
	objectAcl := oss.ObjectACL(oss.ACLPublicRead)

	// 读取文件
	f, err := file.Open()
	if err != nil {
		return
	}

	// 上传
	err = bucket.PutObject(objectName, f, storageType, objectType, objectAcl)
	if err != nil {
		return
	}

	return l.svcCtx.Config.Oss.Path + "/" + objectName, err
}

//endregion
